/* eslint-disable react-hooks/exhaustive-deps */
import React, {
  createContext,
  ReactNode,
  useState,
  useContext,
  useEffect,
  useCallback,
} from 'react';
import {StatusBar, NativeModules} from 'react-native';
import {navigationRef} from '../../App';
import {StatusBarStyleByRouteName} from '../config/devices';

type Props = {
  children: ReactNode;
};
export type statusBarStyleValue = 'light-content' | 'dark-content' | 'default';
type State = {
  appName: string;
  statusBar: boolean;
  statusBackgroundColor: string;
  statusBarStyle: statusBarStyleValue;
  versionName: string;
  isOpenPush: boolean;
};
export type Value = {
  set: (args: State) => void;
  setStatusBarStyles: (style: statusBarStyleValue) => void;
  setStatusBackgroundColor: (backgrouncColor: string) => void;
  setStatusBar: (statusBar: boolean) => void;
  setIsOpenPush: (status: boolean) => void;
  state: State;
};
type Tasks = {
  state: State;
  set: (state: State) => void;
};

const tasks = [] as Array<Tasks>;

const PerformTask = () => {
  for (let i = tasks.length - 1; i >= 0; i--) {
    if (tasks[i] instanceof Object) {
      tasks[i].set(tasks[i].state);
      tasks.splice(i, 1);
    }
  }
};

const sets = new Proxy(tasks, {
  set: (target: Tasks[], key: string | symbol, value: Tasks): boolean => {
    target[key as unknown as number] = value;
    PerformTask();
    return true;
  },
});

const AppContext = createContext<Value | undefined>(undefined);

const stateStatic: State = {
  appName: '短剧App',
  statusBar: true,
  statusBackgroundColor: 'transparent',
  statusBarStyle: 'light-content',
  versionName: 'V1.0.7',
  isOpenPush: true,
};

const AppProvider = function ({children}: Props): JSX.Element {
  const [state, setState] = useState<State>(stateStatic);

  useEffect(() => {
    const unsubscribe = navigationRef.current?.addListener('state', () => {
      const currentRoute = navigationRef.current?.getCurrentRoute();
      if (currentRoute) {
        const curRouteConfig =
          StatusBarStyleByRouteName[currentRoute.name as string];
        setStatusBarStyles(curRouteConfig as statusBarStyleValue);
      }
    });

    NativeModules.bridgeModule.getVersion().then((versionName: string) => {
      sets.push({state: {...state, versionName}, set: setState});
    });

    return () => {
      unsubscribe?.();
    };

  }, []);

  useEffect(() => {
    StatusBar.setBarStyle(state.statusBarStyle);
    StatusBar.setBackgroundColor(state.statusBackgroundColor);
  }, [state]);

  const setStatusBarStyles = useCallback(
    (style: statusBarStyleValue) => {
      sets.push({state: {...state, statusBarStyle: style}, set: setState});
    },
    [state],
  );

  const setStatusBackgroundColor = useCallback(
    (backgroundColor: string) => {
      sets.push({
        state: {...state, statusBackgroundColor: backgroundColor},
        set: setState,
      });
    },
    [state],
  );

  const setStatusBar = useCallback(
    (statusBar: boolean) => {
      sets.push({state: {...state, statusBar: statusBar}, set: setState});
    },
    [state],
  );

  const setIsOpenPush = useCallback(
    (status: boolean) => {
      sets.push({state: {...state, isOpenPush: status}, set: setState});
    },
    [state],
  );

  return (
    <AppContext.Provider
      value={{
        state,
        set: setState as any,
        setStatusBarStyles,
        setStatusBackgroundColor,
        setStatusBar,
        setIsOpenPush,
      }}>
      <StatusBar translucent={state.statusBar} />
      {children}
    </AppContext.Provider>
  );
};

export const useAppContext = function () {
  const ctx = useContext(AppContext);
  return ctx;
};

export default AppProvider;
